iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 16
1

JavaScript 本身是一個非同步的語言。

在 ES6 後,新增了 Promise 的物件來解決同步的問題。

整個 Promise 的流程會如上圖所示。

狀態

首先, Promise 物件,有三種狀態:

  1. pending 待定,狀態未知,還沒執行或被拒絕
  2. fufill 執行完成
  3. reject 拒絕

寫法


let promise = new Promise(function(resolve, reject) {
  // 成功的話,做...
  resolve(value);
  //失敗的話,做...
  reject(value);
});
promise.then(
  // promise 成功執行,也收到結果
  function(result) 
  // promise 被拒絕,收到錯誤結果
  function(error) 
);

以下面的 code 為例,上面的 promise 執行完,就執行下面的 .then()

let promise = new Promise(function(resolve, reject) {
  setTimeout(() => resolve("done!"), 1000);
});

promise.then(
  result => alert(result),
  error => alert(error) 
);

變體 Promise.all vs Promise.race

Promise.all

舉個例子來說,去小吃店吃東西,點了一碗麵,一碗湯,一碗飯。
老闆不一樣一樣的把東西給你,他要等到全部的食物做完以後才送上來。

所有的 promise 都回傳成功了才進入下一個任務,在此之前都是等待,但若其一回傳為失敗就進入 rejected 的處理狀況。

let p1 = new Promise((resolve, reject) => { 
  setTimeout(() => resolve('one'), 1000); 
}); 
let p2 = new Promise((resolve, reject) => { 
  setTimeout(() => resolve('two'), 2000); 
});
let p3 = new Promise((resolve, reject) => {
  setTimeout(() => resolve('three'), 3000);
});
let p4 = new Promise((resolve, reject) => {
  setTimeout(() => resolve('four'), 4000);
});
let p5 = new Promise((resolve, reject) => {
  reject(new Error('reject'));
});


// Using .catch:
Promise.all([p1, p2, p3, p4, p5])
.then(values => { 
  console.log(values);
})
.catch(error => { 
  console.error(error.message)
});

Promise.race

舉個例子來說,到了一家豆花店,點了豆花、燒仙草、湯圓、木瓜牛奶,結果第一樣豆花做好了,送來了,我就決定其他都不要了。

只要有任一 promise 回傳成功就進入下一個任務,其餘的都忽略。

const promise1 = new Promise((resolve, reject) => {
  setTimeout(resolve, 500, 'one');
});

const promise2 = new Promise((resolve, reject) => {
  setTimeout(resolve, 100, 'two');
});

Promise.race([promise1, promise2]).then((value) => {
  console.log(value);
});

限制

  1. 若在 promise 的 callback 內發生錯誤,是不會被捕捉到的,而會直接報錯。
  2. Promise 不能被取消,但可用使用逾時控制來假裝取消承諾。

以上,明天見


上一篇
DAY 15 什麼是 Callback function ?
下一篇
DAY 17 實作 JS 時鐘
系列文
半路出家,文組新手學 Javascript30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言